package ch.wanandroid.lib.banner;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;

import ch.wanandroid.comr.lib.R;

/**
 * @author chnehao
 * @datetime: 2018/9/26 17:52
 * @description:
 */
public abstract class BaseBanner<E,T extends BaseBanner<E,T>> extends RelativeLayout {

    /** 上一个position */
    protected int mLastPositon;
    /** 当前position */
    protected int mCurrentPositon=0;
    /** 多久后开始滚动 */
    private long mDelay=3;
    /** 滚动间隔 */
    private long mPeriod=3000;
    int mScrollSpeed;
    /** 是否正在自动滚动中 */
    private boolean mIsAutoScrolling;
    List<E> mDatas;
    Context mContext;
    /** 设备密度 */
    protected DisplayMetrics mDisplayMetrics;
    /** 切换动画 */
    private Class<? extends ViewPager.PageTransformer> mTransformerClass;
    /** 显示器(小点)的最顶层父容器 */
    private RelativeLayout mRlBottomBarParent;
    private int mItemWidth;
    private int mItemHeight;
    /** 显示器和标题的直接父容器 */
    private LinearLayout mLlBottomBar;
    /** 显示器的的直接容器 */
    private LinearLayout mLlIndicatorContainer;
    /** 标题 */
    private TextView mTvTitle;
    /** 是否自动滚动 */
    private boolean mIsAutoScrollEnable=true;
    ViewPager mViewPager;
    private Handler mHandler = new Handler();
    private int mTitleBgColor;
    private int mTitleColor;
    protected int dataPosition;
    private boolean mIsGuidBanner;
    /**
     * 指示器位置
     */
    private int indicatorGravity;
    Runnable mRunnable=new Runnable() {
        @Override
        public void run() {
            scrollToNextItem(mCurrentPositon);
            mHandler.postDelayed(this,mPeriod);
        }
    };

    public BaseBanner(Context context) {
        this(context, null, 0);
    }

    public BaseBanner(Context context, AttributeSet attrs){
        this(context, attrs, 0);
    }

    public BaseBanner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext=context;
      //  TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BaseBanner);
        TypedArray ta  = context.getTheme().obtainStyledAttributes(attrs, R.styleable.BaseBanner, defStyle, 0);
        //宽除高的倍数，宽为屏幕宽，通过scale设置高
        float scale = ta.getFloat(R.styleable.BaseBanner_bb_scale, -1);
        //默认透明灰
        mTitleBgColor=ta.getColor(R.styleable.BaseBanner_bb_barColor, Color.parseColor("#66000000"));
        mTitleColor=ta.getColor(R.styleable.BaseBanner_bb_textColor,Color.WHITE);
        indicatorGravity = ta.getInt(R.styleable.BaseBanner_bb_indicatorGravity, Gravity.RIGHT);
        float textSize = ta.getDimension(R.styleable.BaseBanner_bb_textSize, sp2px(12.5f));
        mDisplayMetrics = context.getResources().getDisplayMetrics();
        mItemWidth = mDisplayMetrics.widthPixels;
        //get layout_height
        String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height");
        if (scale < 0) {//scale not set in xml
            //设为match，wrap都没内容
            if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
                mItemHeight = LayoutParams.MATCH_PARENT;
            } else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
                mItemHeight = LayoutParams.WRAP_CONTENT;
            } else {
                int[] systemAttrs = {android.R.attr.layout_height};
                TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
                int h = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
                a.recycle();
                mItemHeight = h;
            }
        } else {
//            if (scale > 1) {
//                scale = 1;
//            }
            mItemHeight = (int) (mItemWidth / scale);
        }
        //create ViewPager
        mViewPager =  new ViewPager(context);
     //  mViewPager =  new LoopViewPager(context);
        mViewPager.setId(generateViewId());
        LayoutParams lp = new LayoutParams(mItemWidth, mItemHeight);
        addView(mViewPager, lp);
        //container of indicators and title
        mLlBottomBar = new LinearLayout(context);
        LayoutParams lp2 = new LayoutParams(mItemWidth, LayoutParams.WRAP_CONTENT);
        lp2.addRule(RelativeLayout.ALIGN_BOTTOM, mViewPager.getId());
        addView(mLlBottomBar, lp2);
        mLlBottomBar.setBackgroundColor(mTitleBgColor);
        //不设置的话刚好容纳，不好看
        mLlBottomBar.setPadding((int) dp2px(10), (int) dp2px(10), (int)dp2px(10), (int) dp2px(10));
        mLlBottomBar.setClipChildren(false);
        mLlBottomBar.setClipToPadding(false);
        //addView通过指示器子类获取view
        mLlIndicatorContainer = new LinearLayout(context);
        mLlIndicatorContainer.setGravity(Gravity.CENTER);
        mLlIndicatorContainer.setVisibility(VISIBLE);
        mLlIndicatorContainer.setClipChildren(false);
        mLlIndicatorContainer.setClipToPadding(false);
        // title
        mTvTitle = new TextView(context);
        mTvTitle.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0F));
        mTvTitle.setSingleLine(true);
        mTvTitle.setTextColor(mTitleColor);
        mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        if (indicatorGravity == Gravity.CENTER) {
            mLlBottomBar.setGravity(Gravity.CENTER);
            mLlBottomBar.addView(mLlIndicatorContainer);
        } else {
            if (indicatorGravity == Gravity.RIGHT) {
                mLlBottomBar.setGravity(Gravity.CENTER_VERTICAL);
                mLlBottomBar.addView(mTvTitle);
                mLlBottomBar.addView(mLlIndicatorContainer);
                //指示器在右边，那标题肯定在左边
                mTvTitle.setEllipsize(TextUtils.TruncateAt.END);
                mTvTitle.setGravity(Gravity.LEFT);
            } else if (indicatorGravity == Gravity.LEFT) {
                mLlBottomBar.setGravity(Gravity.CENTER_VERTICAL);
                mLlBottomBar.addView(mLlIndicatorContainer);
                mLlBottomBar.addView(mTvTitle);
                mTvTitle.setEllipsize(TextUtils.TruncateAt.END);
                mTvTitle.setGravity(Gravity.RIGHT);
            }
        }
    }

    /**
     * 最后调用开始滚动
     */
    public T startScroll() {
        if (mDatas == null) {
            throw new IllegalStateException("Data source is empty,you must setSource() before startScroll()");
        }

//        if (mDatas.size() > 0 && mCurrentPositon > mDatas.size()-1) {
//            mCurrentPositon = 0;
//        }
        onTitleSlect(mTvTitle, 0);
        setViewPager();
        //create indicator
        View indicatorViews = onCreateIndicator();
        if (indicatorViews != null) {
            mLlIndicatorContainer.removeAllViews();
            mLlIndicatorContainer.addView(indicatorViews);
        }
        goOnScroll();
        return (T)this;
    }


    /**
     * 开始或继续滚动
     */
    public void goOnScroll() {
        if (!isValid()) {
            return;
        }

        if (mIsAutoScrolling) {
            return;
        }
        if ( mIsAutoScrollEnable&&!mIsGuidBanner) {
            pauseScroll();
            mHandler.postDelayed(mRunnable,mPeriod);
            mIsAutoScrolling = true;
        } else {
            mIsAutoScrolling = false;
        }
    }

    /**
     * 停止滚动
     */
    public void pauseScroll() {
        mHandler.removeCallbacks(mRunnable);
        mIsAutoScrolling = false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                pauseScroll();
                break;
            case MotionEvent.ACTION_UP:
                goOnScroll();
                break;
            case MotionEvent.ACTION_CANCEL:
                goOnScroll();
                break;

        }
        return super.dispatchTouchEvent(ev);
    }
    protected boolean isLoopViewPager() {
        return true;
    }

    /** 设置viewpager */
    private void setViewPager() {
        InnerBannerAdapter mInnerAdapter = new InnerBannerAdapter();
        mViewPager.setAdapter(mInnerAdapter);
        mViewPager.setOffscreenPageLimit(mDatas.size()+2);

        try {
            if (mTransformerClass != null) {
                mViewPager.setPageTransformer(true, mTransformerClass.newInstance());
                if (isLoopViewPager()) {
                    mScrollSpeed = 550;
                    setScrollSpeed();
                }
            } else {
                if (isLoopViewPager()) {
                    mScrollSpeed = 450;
                    setScrollSpeed();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (mInternalPageListener != null) {
            mViewPager.removeOnPageChangeListener(mInternalPageListener);
        }
        mCurrentPositon=mIsGuidBanner?0:(100*mDatas.size());
        mViewPager.setCurrentItem(mCurrentPositon,false);
        mViewPager.addOnPageChangeListener(mInternalPageListener);
    }
    /** 设置滚动速率 */
    private void setScrollSpeed() {
        try {
            Field mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
            FixedSpeedScroller myScroller = new FixedSpeedScroller(mContext, interpolator, mScrollSpeed);
            mScroller.set(mViewPager, myScroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private ViewPager.OnPageChangeListener mInternalPageListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//            if (mOnPageChangeListener != null) {
//                mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
//            }
        }

        @Override
        public void onPageSelected(int position) {
            mCurrentPositon =position;
            dataPosition=position%mDatas.size();
            if (mIsGuidBanner){
                mLlBottomBar.setVisibility(position==mDatas.size()-1?GONE:VISIBLE);
            }
            setCurrentIndicator(dataPosition);
            onTitleSlect(mTvTitle, dataPosition);
            mLastPositon = dataPosition;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
//            if (mOnPageChangeListener != null) {
//                mOnPageChangeListener.onPageScrollStateChanged(state);
//            }
        }
    };
    /** 滚动到下一个item */
    private void scrollToNextItem(int position) {
        position++;
        Log.d("sdfsfas",""+position);
        mViewPager.setCurrentItem(position);
    }

    protected boolean isValid() {
        if (mViewPager == null) {
            return false;
        }
        if (mDatas == null || mDatas.size() == 0) {
            return false;
        }
        return true;
    }

    /**滚动间隔
     * @param mPeriod
     * @return
     */
    public T setPeriod(int mPeriod){
        this.mPeriod=mPeriod;
        return (T)this;
    }

    /**数据
     * @param mDatas
     * @return
     */
    public T setData(List<E> mDatas){
        this.mDatas=mDatas;
        return (T)this;
    }

    /**页面切换动画
     * @param transformerClass
     * @return
     */
    public T setTransformerClass(Class<? extends ViewPager.PageTransformer> transformerClass) {
        this.mTransformerClass = transformerClass;
        return  (T)this;
    }

    /**
     * @param mTitleColor
     * @return
     */
    public T setTitleColor(int mTitleColor){
        this.mTitleColor=mTitleColor;
        return (T)this;
    }

    /**指示器位置，标题就在另一侧
     * @param indicatorGravity,Gravity.CENTER,Left,Right
     * @return
     */
    public T setIndicatorGravity(int indicatorGravity){
        this.indicatorGravity=indicatorGravity;
        return (T)this;
    }

    public T setWidth(int mItemWidth){
        this.mItemWidth=mItemWidth;
        return (T)this;
    }
    public T setHeight(int mItemHeight){
        this.mItemHeight=mItemHeight;
        return (T)this;
    }
    /**PageAdapter布局
     * @param position
     * @return
     */
    public abstract View onCreateItemView(int position);


    /**切换标题
     * @param tv
     * @param position
     */
    public abstract void onTitleSlect(TextView tv, int position);

    public void setTitleBgColor(int mTitleBgColor){
        this.mTitleBgColor=mTitleBgColor;
    }

    public T setGuidBanner(boolean mIsGuidBanner){
        this.mIsGuidBanner=mIsGuidBanner;
        return (T)this;
    }
    /**创建显示器
     * @return
     */
    public abstract View onCreateIndicator();

    public abstract void setCurrentIndicator(int position);

    private class InnerBannerAdapter extends PagerAdapter {
        @Override
        public int getCount() {
            return mIsGuidBanner?mDatas.size():Integer.MAX_VALUE;
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            final int s=position%mDatas.size();
            if (mIsGuidBanner){
                mLlBottomBar.setBackgroundColor(Color.TRANSPARENT);
            }
            View inflate = onCreateItemView(s);
            inflate.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnItemClickL != null) {
                        mOnItemClickL.onItemClick(s);
                    }
                }
            });
            container.addView(inflate);

            return inflate;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
    }

    private OnItemClickL mOnItemClickL;

    public void setOnItemClickL(OnItemClickL onItemClickL) {
        this.mOnItemClickL = onItemClickL;
    }

    public interface OnItemClickL {
        void onItemClick(int position);
    }

    protected int dp2px(float dp) {
        float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5F);
    }

    private float sp2px(float sp) {
        final float scale = mContext.getResources().getDisplayMetrics().scaledDensity;
        return sp * scale;
    }
}
